package com.ticket.sass.admin.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ticket.sass.admin.business.DouyinGoodBusiness;
import com.ticket.sass.admin.dto.input.douyin.DouyinGoodExchangeSettingInput;
import com.ticket.sass.admin.dto.input.douyin.DouyinGoodListInput;
import com.ticket.sass.admin.dto.input.douyin.DouyinuGoodUpdInput;
import com.ticket.sass.admin.dto.input.douyin.GetDouyinGoodExchangeSettingInput;
import com.ticket.sass.admin.dto.output.douyin.DouyinGoodExchangeSettingOutput;
import com.ticket.sass.admin.dto.output.douyin.DouyinGoodListOutput;
import com.ticket.sass.admin.model.PageModel;
import com.ticket.sass.admin.service.impl.CouponServiceImpl;
import com.ticket.sass.admin.service.impl.DouyinGoodsExchangeSettingServiceImpl;
import com.ticket.sass.admin.service.impl.DouyinGoodServiceImpl;
import com.ticket.sass.admin.service.impl.DouyinLocalLifeConfigServiceImpl;
import com.ticket.sass.admin.util.ModelUtil;
import com.ticket.sass.common.douyin.openapi.Client;
import com.ticket.sass.common.douyin.openapi.enums.GoodsStatus;
import com.ticket.sass.common.douyin.openapi.resposne.CreateClientTokenData;
import com.ticket.sass.common.douyin.openapi.resposne.ListGoodsData;
import com.ticket.sass.common.entity.tenant.CouponEntity;
import com.ticket.sass.common.entity.tenant.DouyinGoodEntity;
import com.ticket.sass.common.entity.tenant.DouyinGoodsExchangeSettingEntity;
import com.ticket.sass.common.entity.tenant.DouyinLocalLifeConfigEntity;
import com.ticket.sass.common.entity.tenant.enums.DouyinGoodProductType;
import com.ticket.sass.common.entity.tenant.enums.DouyinGoodsOnlineStatus;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BadRequestException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ywb
 * @date 2024-07-19 11:25
 */
@Slf4j
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class DouyinGoodBusinessImpl implements DouyinGoodBusiness {
    final ModelUtil modelUtil;
    final DouyinGoodServiceImpl service;
    final CouponServiceImpl couponService;
    final DouyinGoodServiceImpl dyGoodService;
    final DouyinLocalLifeConfigServiceImpl fyLocalLifeConfigService;
    final DouyinGoodsExchangeSettingServiceImpl dyGoodsExchangeSettingService;
    
    @Override
    public PageModel<DouyinGoodListOutput> list(DouyinGoodListInput input) {
        IPage<DouyinGoodEntity> page = service.iPage(input);
        return new PageModel<>(
            page.getTotal(),
            page.getRecords().stream().map(DouyinGoodListOutput::fromEntity).collect(Collectors.toList())
        );
    }
    @Override
    public void exchangeSetting(DouyinGoodExchangeSettingInput exchangeSetting) {
        // 获取商品信息
        DouyinGoodEntity product = getProduct(exchangeSetting.getProductId());
        
        // 获取当前的所有设置
        List<DouyinGoodsExchangeSettingEntity> currentSettings = getCurrentSettings(exchangeSetting.getProductId());
        
        // 将当前设置转换为 Map，方便查找
        Map<Long, DouyinGoodsExchangeSettingEntity> currentSettingMap = mapCurrentSettings(currentSettings);
        
        // 分类处理新提交的设置
        List<DouyinGoodsExchangeSettingEntity> newSettings = new ArrayList<>();
        List<DouyinGoodsExchangeSettingEntity> updateSettings = new ArrayList<>();
        List<Long> newSettingCouponIds = new ArrayList<>();
        
        for (DouyinGoodExchangeSettingInput.ExchangeSetting setting : exchangeSetting.getExchangeSettings()) {
            DouyinGoodsExchangeSettingEntity currentSetting = currentSettingMap.get(setting.getCouponId());
            if (currentSetting == null) {
                // 如果当前设置中不存在，则新增
                newSettings.add(new DouyinGoodsExchangeSettingEntity(
                    exchangeSetting.getProductId(),
                    product.getSkuId(),
                    setting.getCouponId(),
                    setting.getNumber()
                ));
            } else {
                // 如果存在，则更新
                currentSetting.setNumber(setting.getNumber());
                updateSettings.add(currentSetting);
            }
            newSettingCouponIds.add(setting.getCouponId());
        }
        
        // 批量保存新设置
        if (!newSettings.isEmpty()) {
            dyGoodsExchangeSettingService.saveBatch(newSettings);
        }
        
        // 批量更新设置
        if (!updateSettings.isEmpty()) {
            dyGoodsExchangeSettingService.updateBatchById(updateSettings);
        }
        
        // 批量删除不再存在的设置
        List<Long> currentSettingIdsToDelete = currentSettings.stream()
            .filter(setting -> !newSettingCouponIds.contains(setting.getCouponId()))
            .map(DouyinGoodsExchangeSettingEntity::getId)
            .collect(Collectors.toList());
        if (!currentSettingIdsToDelete.isEmpty()) {
            dyGoodsExchangeSettingService.removeByIds(currentSettingIdsToDelete);
        }
    }
    
    private DouyinGoodEntity getProduct(String productId) {
        DouyinGoodEntity product = dyGoodService.getOne(new QueryWrapper<DouyinGoodEntity>().eq("product_id", productId));
        if (Objects.isNull(product)) {
            throw new BadRequestException(
                ErrorCode.BAD_REQUEST,
                "商品不存在"
            );
        }
        return product;
    }
    
    private List<DouyinGoodsExchangeSettingEntity> getCurrentSettings(String productId) {
        return dyGoodsExchangeSettingService.list(new QueryWrapper<DouyinGoodsExchangeSettingEntity>().eq("product_id", productId));
    }
    
    private Map<Long, DouyinGoodsExchangeSettingEntity> mapCurrentSettings(List<DouyinGoodsExchangeSettingEntity> currentSettings) {
        return currentSettings.stream()
            .collect(Collectors.toMap(DouyinGoodsExchangeSettingEntity::getCouponId, setting -> setting));
    }
    
    
    @Override
    public DouyinGoodExchangeSettingOutput getExchangeSetting(GetDouyinGoodExchangeSettingInput input) {
        // 从服务中获取所有相关的兑换设置实体
        List<DouyinGoodsExchangeSettingEntity> entities = dyGoodsExchangeSettingService.getListBy(input.getProductId());
        
        Map<Long, CouponEntity> longCouponEntityMap = couponService.mapByIds(entities.stream().map(DouyinGoodsExchangeSettingEntity::getCouponId).collect(Collectors.toList()));
        
        DouyinGoodExchangeSettingOutput result = new DouyinGoodExchangeSettingOutput();
        result.setProductId(input.getProductId());
        
        // 构建ExchangeSetting列表
        List<DouyinGoodExchangeSettingOutput.ExchangeSetting> exchangeSettings = entities.stream().map(entity -> {
            DouyinGoodExchangeSettingOutput.ExchangeSetting setting = new DouyinGoodExchangeSettingOutput.ExchangeSetting();
            setting.setCouponId(entity.getCouponId());
            setting.setNumber(entity.getNumber());
            setting.setEffectiveDuration(entity.getEffectiveDuration());
            setting.setCouponName(longCouponEntityMap.getOrDefault(entity.getCouponId(), new CouponEntity()).getName());
            return setting;
        }).collect(Collectors.toList());
        
        result.setExchangeSettings(exchangeSettings);
        return result;
    }
    
    @Override
    public void sync() {
        Optional<DouyinLocalLifeConfigEntity> optionalEntity = Optional.ofNullable(fyLocalLifeConfigService.getOne(null));

        DouyinLocalLifeConfigEntity entity;
        if (optionalEntity.isPresent()) {
            entity = optionalEntity.get();
            Client client = new com.ticket.sass.common.douyin.openapi.Client(entity.getClientKey(), entity.getClientSecret(), entity.getAccountId(), entity.getPodId());

            CreateClientTokenData clientToken = client.createClientToken();
            log.info("clientToken[{}]", clientToken);
            
            client.setAccessToken(Objects.requireNonNull(clientToken.getAccessToken()));
            
            List<DouyinGoodEntity> syncData = getSyncData(client);
            
            Map<String, DouyinGoodEntity> stringDouyinGoodEntityMap = dyGoodService.productIdMap();

            // 使用Stream API进行分组
            Map<Boolean, List<DouyinGoodEntity>> collect = syncData.stream()
                .collect(Collectors.partitioningBy(
                    e -> stringDouyinGoodEntityMap.containsKey(e.getProductId())
                ));

            // 获取需要添加和更新的商品列表
            List<DouyinGoodEntity> adds = collect.get(false);
            List<DouyinGoodEntity> updates = collect.get(true).stream()
                .peek(e -> {
                    e.setId(stringDouyinGoodEntityMap.get(e.getProductId()).getId());
                    e.setRedeemable(stringDouyinGoodEntityMap.get(e.getProductId()).isRedeemable());
                })
                .collect(Collectors.toList());

            // 批量添加新商品
            if (!adds.isEmpty()) {
                dyGoodService.saveBatch(adds);
            }

            // 批量更新现有商品
            if (!updates.isEmpty()) {
                dyGoodService.updateBatchById(updates);
            }
            
        } else {
            throw new BadRequestException(
                ErrorCode.BUSINESS_ERROR,
                "暂无配置"
            );
        }
    }
    
    @Override
    public void upd(DouyinuGoodUpdInput input) {
        service.update(new UpdateWrapper<DouyinGoodEntity>().eq("product_id", input.getProductId()).set("is_redeemable", input.getRedeemable()));
    }
    
    private List<DouyinGoodEntity> getSyncData(com.ticket.sass.common.douyin.openapi.Client client) {
        List<DouyinGoodEntity> list = new ArrayList<>();
        list.addAll(toEntity(client.listGoods(new Client.ListGoodsQry("", 50, GoodsStatus.ONLINE))));
        list.addAll(toEntity(client.listGoods(new Client.ListGoodsQry("", 50, GoodsStatus.OFFLINE))));
        list.addAll(toEntity(client.listGoods(new Client.ListGoodsQry("", 50, GoodsStatus.DISABLED))));
        return list;
    }
    
    private List<DouyinGoodEntity> toEntity(ListGoodsData listGoodsData) {
        List<DouyinGoodEntity> list = new ArrayList<>();
        
        // 假设我们同步第一个产品数据
        if (!CollectionUtils.isEmpty(listGoodsData.getProducts())) {
            for (ListGoodsData.ProductContainer productContainer:listGoodsData.getProducts()) {
                ListGoodsData.Product product = productContainer.getProduct();
                ListGoodsData.Sku sku = productContainer.getSku();

                DouyinGoodEntity entity = new DouyinGoodEntity();

                entity.setProductId(product.getProductId());
                entity.setProductName(product.getProductName());
                entity.setSkuId(sku.getSkuId());
                entity.setProductType(DouyinGoodProductType.Companion.valueOf((short) product.getProductType()));
                entity.setOnlineStatus(DouyinGoodsOnlineStatus.Companion.valueOf((short)productContainer.getOnlineStatus()));
              
                entity.setSoldStartTime(convertToLocalDateTime(product.getSoldStartTime()));
                entity.setSoldEndTime(convertToLocalDateTime(product.getSoldEndTime()));
                entity.setRemark(""); // 没有找到对应字段，暂设为空
                entity.setRedeemable(true);
                list.add(entity);
            }
        }

        return list;
    }
    
    private LocalDateTime convertToLocalDateTime(Long timeStamp) {
        Instant instant = Instant.ofEpochSecond(timeStamp);
        // 将Instant对象转换为特定时区的LocalDateTime对象
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }
}
